package com.wms.dao.impl;

import com.wms.dao.BaseDao;
import com.wms.model.PageBean;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @author This
 * @version 1.0
 * @date 2019/7/9 17:52
 */
public class BaseDaoImpl<T> implements BaseDao<T> {

    /**
     * 真实类
     */
    private Class<T> modelClass;

    @SuppressWarnings("unchecked")
    public BaseDaoImpl() {
        // 获取泛型真是类型
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        //真实类型数组
        Type[] types = pt.getActualTypeArguments();
        modelClass = (Class<T>) types[0];
    }

    @Autowired
    protected HibernateTemplate template;

    @Override
    public void save(T model) {
        this.template.save(model);
    }

    @Override
    public void delete(T model) {
        this.template.delete(model);
    }

    @Override
    public void update(T model) {
        this.template.update(model);
    }

    @Override
    public T find(Serializable id) {
        return this.template.get(modelClass, id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findAll() {
        String hql = "from " + modelClass.getSimpleName();
        return this.template.find(hql);
    }

    /**
     * 执行部分更新
     *
     * @param hql  hql语句
     * @param objs 参数
     */
    @Override
    public int executeUpdate(String hql, Object... objs) {
        // 获取当前session
        Session session = template.getSessionFactory().getCurrentSession();

        // 查询对象,参数按顺序
        // Update User set xxx=? where xx=?;
        Query query = session.createQuery(hql);

        // 设置参数
        for (int i = 0; i < objs.length; i++) {
            query.setParameter(i, objs[i]);
        }

        // 执行语句
        return query.executeUpdate();
    }

    /**
     * 映射文件中设置的hql语句
     *
     * @param queryName 在映射文件中配置的query名字
     * @param objs      参数
     */
    @Override
    public int executeUpdateByQueryName(String queryName, Object... objs) {
        // 获取session
        Session session = template.getSessionFactory().getCurrentSession();

        // 从映射文件中查找hql，并返回query对象
        Query query = session.getNamedQuery(queryName);
        // 设置参数
        for (int i = 0; i < objs.length; i++) {
            query.setParameter(i, objs[i]);
        }
        // 执行
        return query.executeUpdate();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> findByCondition(DetachedCriteria dc) {
        return this.template.findByCriteria(dc);
    }

    /**
     * 批量插入
     *
     * @param ts 插入数据
     */
    @Override
    public void insertAll(List<T> ts) {
        this.template.saveOrUpdateAll(ts);
    }

    @Override
    public void pageQuery(PageBean<T> pb) {
        try {
            String hql;
            Long count;
            if (pb.getCondition() != null && pb.getCondition().length() > 0) {
                hql = "from " + modelClass.getSimpleName() + " where " + pb.getCondition();
                count = count(modelClass.newInstance(), pb.getCondition());
            } else {
                hql = "from " + modelClass.getSimpleName();
                count = count(modelClass.newInstance(), null);
            }
            System.out.println("HQL：" + hql);
            pb.setTotal(count.intValue());
            //开始页数
            int start = (pb.getCurrentPage() - 1) * pb.getPageSize();
            //条数
            int length = pb.getPageSize();
            System.out.println(pb.getCondition());
            // 获取session
            Session session = template.getSessionFactory().getCurrentSession();
            Query query = session.createQuery(hql);
            query.setFirstResult(start);
            query.setMaxResults(length);
            List<T> list = query.list();
            pb.setRows(list);
        } catch (Exception e) {

        }

    }

    @Override
    public Long count(T t, String condition) {
        String hql;
        if (StringUtils.isNotEmpty(condition)) {
            hql = "select count(*) from " + modelClass.getSimpleName() + " where " + condition;
        } else {
            hql = "select count(*) from " + modelClass.getSimpleName();
        }
        Session session = template.getSessionFactory().getCurrentSession();
        Query query = session.createQuery(hql);
        return (Long) query.uniqueResult();
    }

    @Override
    public void deleteAll(String condition) {
        String hql = "delete from " + modelClass.getSimpleName() + " where " + condition;
        Session session = template.getSessionFactory().getCurrentSession();
        Query query = session.createQuery(hql);
        query.executeUpdate();
    }

    @Override
    public List<T> findByCondition(String condition, Object... param) {
        String hql = "from " + modelClass.getSimpleName() + " ";
        if (StringUtils.isNotEmpty(condition)) {
            hql += " where " + condition;
        }
        Session session = template.getSessionFactory().getCurrentSession();
        Query query = session.createQuery(hql);
        if (null != param && param.length > 0) {
            for (int i = 0; i < param.length; i++) {
                query.setParameter(i, param[i]);
            }
        }
        return query.list();
    }


}
